﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace EPlusReport
{
    public class pub
    {

        public static bool IsNumber(object o)
        {
            if (o.ToString().Length > 1)
            {
                if (o.ToString().Substring(0, 1) == "0" && o.ToString().Substring(1, 1) != ".")
                {
                    return false;
                }
            }

            int i = 0;
            return int.TryParse(o.ToString(), out i);

        }

        public static bool IsDateTime(object o)
        {
            DateTime dt = DateTime.Now;
            return DateTime.TryParse(o.ToString(), out dt);
        }

        public static string FieldValue(object o, string fmt)
        {
            try
            {
                if (o is DateTime)
                {
                    DateTime t = (DateTime)o;
                    if (string.IsNullOrEmpty(fmt))
                    {
                        if (t.Hour + t.Minute + t.Second == 0)

                            return t.ToString("yyyy-MM-dd");
                        else
                            return t.ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    else
                    {
                        return t.ToString(fmt);
                    }
                }
                else
                    if (o.GetType() == DBNull.Value.GetType())
                    {
                        return null;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(fmt))
                        {
                            if (o.GetType() == double.MaxValue.GetType()
                                || o.GetType() == float.MaxValue.GetType()
                                || o.GetType() == int.MaxValue.GetType()
                                )
                            {

                                return double.Parse(string.Concat(o)).ToString(fmt);
                            }
                            else
                                return o.ToString();
                        }
                        else
                        {
                            return o.ToString();
                        }
                    }
            }
            catch
            {
                return "";
            }
        }

        public static string FieldValue(object o)
        {
            return FieldValue(o, null);
        }

        public static object FieldValueObj(object o, string fmt)
        {
            try
            {
                if (o is DateTime)
                {
                    DateTime t = (DateTime)o;
                    if (string.IsNullOrEmpty(fmt))
                    {
                        if (t.Hour + t.Minute + t.Second == 0)

                            return t.ToString("yyyy-MM-dd");
                        else
                            return t.ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    else
                    {
                        return t.ToString(fmt);
                    }
                }
                else
                    if (o.GetType() == DBNull.Value.GetType())
                    {
                        return null;
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(fmt))
                        {
                            if (o.GetType() == double.MaxValue.GetType()
                                || o.GetType() == float.MaxValue.GetType()
                                || o.GetType() == int.MaxValue.GetType()
                                )
                            {
                                return double.Parse(string.Concat(o)).ToString(fmt);
                            }
                            else
                            {
                                return o;
                            }
                        }
                        else
                        {
                            return o;
                        }
                    }
            }
            catch
            {
                return "";
            }
        }

        public static string[] Matches(string s, string exp)
        {
            var match = System.Text.RegularExpressions.Regex.Matches(s, exp.Replace("*", "\\S+?"));
            List<string> lst = new List<string>();
            for (int i = 0; i < match.Count; i++)
            {
                lst.Add(match[i].Value);
            }
            return lst.ToArray();
        }

        /// <summary>
        /// Conert String Contains Datetime format.[yyyyMMdd+days] || [yyyyMMdd++months]
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static string ConvertDateString(string s)
        {
            s = s.Replace("@host", System.Environment.MachineName).Replace("@user", Environment.UserName);

            string[] fs = Matches(s, "{*}");
            foreach (string ss in fs)
            {
                string s1 = ss.Substring(1, ss.Length - 2);
                string[] mm = s1.Split(',');
                if (mm.Length > 1)
                {
                    try
                    {
                        int i1 = int.Parse(mm[1]);
                        int i2 = s1.Length;
                        if (mm.Length > 2)
                        {
                            i2 = int.Parse(mm[2]);
                        }

                        if (mm[0].Length < i1 + i2)
                        {
                            s = s.Replace(ss, mm[0].Substring(i1));
                        }
                        else
                        {
                            s = s.Replace(ss, mm[0].Substring(i1, i2));
                        }
                    }
                    catch { }
                }
            }
            return ConvertDateString(s, "[", "]");
        }


        /// <summary>
        /// convert date string with delimited [yyyyMMdd+idays] || [yyyyMMdd++imonths]
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sStart"></param>
        /// <param name="sEnd"></param>
        /// <returns></returns>
        public static string ConvertDateString(string s, string sStart, string sEnd)
        {
            return ConvertDateString(s, sStart, sEnd, DateTime.Now);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sStart"></param>
        /// <param name="sEnd"></param>
        /// <param name="t1"></param>
        /// <returns></returns>
        public static string ConvertDateString(string s, string sStart, string sEnd, DateTime t1)
        {
            if (string.IsNullOrEmpty(sEnd))
                sEnd = sStart;

            while (true)
            {
                int p1 = s.IndexOf(sStart);
                if (p1 > -1)
                {
                    int p3 = s.IndexOf(sStart, p1 + sStart.Length);

                    int p2 = s.IndexOf(sEnd, p1 + sStart.Length);

                    if (p3 > p1 && p3 < p2)
                    {
                        p1 = p3;
                    }

                    if (p2 > -1)
                    {
                        string v = s.Substring(p1 + sStart.Length, p2 - p1 - sStart.Length);
                        int idays = 0;
                        if ((v.StartsWith("&") || v.StartsWith("#")) && v.Length > 15)
                        {
                            if (DateTime.TryParse(t1.ToString(v.Substring(1, 10)), out t1))
                            {
                                v = v.Substring(12);
                            }
                        }

                        if (v.Contains("+"))
                        {
                            string sadd = v.Substring(v.LastIndexOf("+") + 1);
                            if (sadd.ToLower().EndsWith("h"))
                            {
                                t1 = t1.AddHours(int.Parse(sadd.TrimEnd('h')));
                                v = t1.ToString(v.Substring(0, v.IndexOf("+")));
                            }
                            else
                                if (sadd.ToLower().EndsWith("m"))
                                {
                                    t1 = t1.AddMonths(int.Parse(sadd.TrimEnd('m')));
                                    v = t1.ToString(v.Substring(0, v.IndexOf("+")));
                                }
                                else
                                {

                                    int.TryParse(v.Substring(v.LastIndexOf("+") + 1), out idays);
                                    if (v.Contains("++"))
                                    {
                                        v = t1.AddMonths(idays).ToString(v.Substring(0, v.IndexOf("+")));
                                    }
                                    else
                                    {
                                        v = t1.AddDays(idays).ToString(v.Substring(0, v.IndexOf("+")));
                                    }
                                }
                            s = string.Concat(s.Substring(0, p1), v, s.Substring(p2 + sEnd.Length));
                        }
                        else
                        {
                            if (v == "d")
                            {
                                v = t1.ToString("dd").TrimStart('0');
                            }
                            else
                            {
                                v = t1.ToString(v);
                            }
                            s = string.Concat(s.Substring(0, p1), v, s.Substring(p2 + sEnd.Length));
                        }

                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            //s = s.Replace(sStart + sStart, sStart);
            //s = s.Replace(sEnd + sEnd, sEnd);
            return s;
        }


        public static System.Data.DataTable SelectColumns(System.Data.DataTable dt, string columns)
        {
            System.Data.DataTable dtcopy = dt.Copy();
            if (string.IsNullOrEmpty(columns))
                return dtcopy;

            string cols = "";
            foreach (System.Data.DataColumn dc in dt.Columns)
            {
                bool f = false;
                foreach (string s in columns.Split(','))
                {
                    f = s.ToUpper() == dc.ColumnName.ToUpper();
                    if (f)
                        break;
                }

                if (!f)
                {
                    cols += dc.ColumnName + ",";
                }
            }

            if (cols.Length > 0)
            {
                foreach (string s in cols.Split(','))
                {
                    if (!string.IsNullOrEmpty(s))
                    {
                        dtcopy.Columns.Remove(s);
                    }
                }
            }
            return dtcopy;
        }

        public static Boolean isWinForm
        {
            get
            {
                return Process.GetCurrentProcess().MainWindowHandle != IntPtr.Zero;
            }
        }

        public static bool PingConnected(string hostName, int iTimeoutMs)
        {
            System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping();
            bool ret = false;
            try
            {
                ret = p.Send(hostName, iTimeoutMs).Status == System.Net.NetworkInformation.IPStatus.Success;
            }
            catch
            {
                //MessageBox.Show(string.Concat("Connect ", sdrServer, " Error! ", Environment.NewLine, ex1.Message));
            }
            return ret;
        }

        public static bool SQLBool(object val)
        {
            bool ret = false;
            try
            {
                ret = val.ToString().ToUpper() == "TRUE";
            }
            catch { }
            return ret;
        }


        #region UI Control

        public static string VersionOfExecute
        {
            get
            {
                string tsVerion = System.Reflection.Assembly.GetEntryAssembly().FullName;
                string[] lines = tsVerion.Split(',');
                if (lines.Length > 2)
                    tsVerion = lines[1];
                return tsVerion;
            }
        }

        public static string Version
        {
            get
            {
                string tsVerion = System.Reflection.Assembly.GetExecutingAssembly().FullName;
                string[] lines = tsVerion.Split(',');
                if (lines.Length > 2)
                    tsVerion = lines[1];
                return tsVerion;
            }
        }

        #endregion

        public static System.Data.DataTable ENUM2DT(Type ty)
        {
            System.Data.DataTable dt = new System.Data.DataTable(ty.Name);
            dt.Columns.Add("Name", "".GetType());
            dt.Columns.Add("Value", "".GetType());
            Array ar = Enum.GetValues(ty);
            for (int i = 0; i < ar.Length; i++)
            {
                dt.Rows.Add(Enum.GetName(ty, ar.GetValue(i)), (int)ar.GetValue(i));
            }
            return dt;
        }

        public static string[] split_ext(string line, string delimited)
        {
            var values = new List<string>();
            string ed = "\"";
            int p = line.IndexOf(delimited);
            string ss = "";
            while (p > -1)
            {
                if (line.StartsWith(ed))
                {
                    int p2 = line.IndexOf(ed + delimited);
                    if (p2 > 0)
                    {
                        ss = line.Substring(1, p2 - 1);
                        line = line.Substring(p2 + delimited.Length + 1);
                    }
                }
                else
                {
                    ss = line.Substring(0, p);
                    line = line.Substring(p + delimited.Length);
                }
                values.Add(ss);
                p = line.IndexOf(delimited);
            }
            values.Add(line.TrimStart(ed.ToCharArray()).TrimEnd(ed.ToCharArray()));
            return values.ToArray();
        }


        /// <summary>
        /// Update Field With System.Data.DataSet with first row
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sStart"></param>
        /// <param name="sEnd"></param>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static string UpdateFieldName(string s, string sStart, string sEnd, DataSet ds)
        {
            if (string.IsNullOrEmpty(s))
                return s;

            if (string.IsNullOrEmpty(sEnd))
                sEnd = sStart;

            int p0 = 0;

            while (true)
            {
                int p1 = s.IndexOf(sStart);
                if (p1 > -1)
                {
                    int p3 = s.IndexOf(sStart, p1 + sStart.Length);

                    int p2 = s.IndexOf(sEnd, p1 + sStart.Length);
                    p0 = p2;
                    if (p3 > p1 && p3 < p2)
                    {
                        p1 = p3;
                    }

                    if (p2 > -1)
                    {
                        string v = s.Substring(p1 + sStart.Length, p2 - p1 - sStart.Length);
                        int iRow = 0;
                        string[] vfield = v.Split('.');
                        if (vfield.Length == 2)
                        {
                            foreach (System.Data.DataTable dt in ds.Tables)
                            {
                                if (dt.TableName.ToUpper() == vfield[0].ToUpper())
                                {
                                    if (dt.Columns.Contains(vfield[1]))
                                    {
                                        if (iRow < dt.Rows.Count)
                                        {
                                            v = string.Concat(dt.Rows[iRow][vfield[1]]);
                                        }
                                        else
                                        {
                                            v = "";
                                        }
                                        s = string.Concat(s.Substring(0, p1), v, s.Substring(p2 + sEnd.Length));
                                        p0 = 0;
                                    }
                                }
                            }
                        }
                        else
                        {
                            foreach (System.Data.DataTable dt in ds.Tables)
                            {
                                if (dt.Columns.Contains(vfield[0]))
                                {
                                    if (iRow < dt.Rows.Count)
                                    {
                                        v = string.Concat(dt.Rows[iRow][vfield[0]]);
                                    }
                                    else
                                    {
                                        v = "";
                                    }
                                    s = string.Concat(s.Substring(0, p1), v, s.Substring(p2 + sEnd.Length));
                                    p0 = 0;
                                }
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
            return s;
        }

        /// <summary>
        /// Update Field With System.Data.DataTable
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sStart"></param>
        /// <param name="sEnd"></param>
        /// <param name="dt"></param>
        /// <param name="iRow"></param>
        /// <returns></returns>
        public static string UpdateFieldName(string s, string matchStr, DataTable dt, int iRow)
        {
            if (string.IsNullOrEmpty(s))
                return s;


            if (dt == null) return s;

            DataRow dr = dt.NewRow();

            if (dt.Rows.Count > iRow)
                dr = dt.Rows[iRow];

            return string.Concat(getValue(s, matchStr, dr));
        }

        public static object getValue(object v, string matchStr, DataRow dr)
        {
            string ss = string.Concat(v);
            bool isfound = false;
            foreach (string exp in Matches(ss, matchStr))
            {
                isfound = true;
                string f = exp;
                foreach (string s in matchStr.Split('*'))
                {
                    f = f.Replace(s, "");
                }

                string[] ff = (f + ",,,,").Split(',');
                if (dr == null)
                {
                    if (ss == exp && !string.IsNullOrEmpty(ff[2]))
                    {
                        try
                        {
                            if (ff[2].Contains("."))
                            {
                                return double.Parse(ff[2]);
                            }
                            else
                            {
                                return int.Parse(ff[2]);
                            }
                        }
                        catch
                        {
                            return ss.Replace(exp, ff[2]);
                        }
                    }
                    ss = ss.Replace(exp, ff[2]);
                    continue;
                }

                string fmt = ff[3];
                if ((ff[0].StartsWith("sum(")
                     || ff[0].StartsWith("avg(")
                     || ff[0].StartsWith("count(")
                    ) && ff[0].EndsWith(")"))
                {
                    try
                    {
                        if (ss == exp)
                        {
                            return pub.FieldValueObj(dr.Table.Compute(ff[0], ff[1]), fmt);
                        }
                        else
                        {
                            ss = ss.Replace(exp, pub.FieldValue(dr.Table.Compute(ff[0], ff[1]), fmt));
                        }
                    }
                    catch
                    {
                        ss = "#error";
                    }
                }
                else
                {
                    if (ff[0].Contains("=") && dr.Table.Columns.Contains(ff[1]))
                    {
                        string ff0 = ff[0];
                        ff[0] = ff[1];
                        ff[1] = ff0;
                    }

                    if (dr.Table.Columns.Contains(ff[0]))
                    {
                        if (ff[1].Contains("="))
                        {
                            string[] fff = ff[1].Split('=');
                            if (dr.Table.Columns.Contains(fff[0]))
                            {
                                if (string.Concat(dr[fff[0]]).ToLower() == fff[1].ToLower())
                                {
                                    if (ss == exp)
                                    {
                                        return pub.FieldValueObj(dr[ff[0]], fmt);
                                    }
                                    else
                                    {
                                        ss = ss.Replace(exp, pub.FieldValue(dr[ff[0]], fmt));
                                    }
                                }
                            }
                            else
                            {
                                ss = ss.Replace(exp, "");
                            }
                        }
                        else
                        {
                            if (ss == exp || string.IsNullOrEmpty(ss))
                            {
                                return pub.FieldValueObj(dr[ff[0]], fmt);
                            }
                            else
                            {
                                ss = ss.Replace(exp, pub.FieldValue(dr[ff[0]], fmt));
                            }
                        }
                    }
                }
            }
            if (!isfound)
            {
                return v;
            }
            else
            {
                return ss;
            }
        }

        public static string fieldvalue(object obj)
        {
            string ret = string.Concat(obj);
            switch (obj.GetType().Name.ToLower())
            {
                case "date":
                case "datetime":
                    DateTime d1 = (DateTime)obj;
                    if (d1.Hour + d1.Minute + d1.Second > 0)
                    {
                        ret = d1.ToString("yyyy/MM/dd hh:mm:ss");
                    }
                    else
                    {
                        ret = d1.ToString("yyyy/MM/dd");
                    }
                    break;
            }

            return ret;
        }

        /// <summary>
        /// Update Field With System.Collections.Hashtable
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sStart"></param>
        /// <param name="sEnd"></param>
        /// <param name="htTable"></param>
        /// <returns></returns>
        public static object UpdateFieldName(string sourceStr, string matchStr, DataRow dr)
        {
            if (string.IsNullOrEmpty(sourceStr))
                return sourceStr;

            string s = sourceStr;
            foreach (string exp in Matches(sourceStr, matchStr))
            {
                string f = exp;
                foreach (string s1 in matchStr.Split('*'))
                {
                    f = f.Replace(s1, "");
                }
                string[] ff = (f + ",,,,,").Split(',');

                if (dr == null)
                {
                    s = s.Replace(exp, FieldValue(dr[ff[0]]));
                }
                else
                    if (dr.Table.Columns.Contains(ff[0]))
                    {
                        if (exp == sourceStr)
                        {
                            return FieldValueObj(dr[ff[0]], ff[2]);
                        }
                        else
                        {
                            s = s.Replace(exp, FieldValue(dr[ff[0]]));
                        }
                    }
            }
            return s;
        }

        /// <summary>
        /// Update Field With System.Collections.Hashtable
        /// </summary>
        /// <param name="s"></param>
        /// <param name="sStart"></param>
        /// <param name="sEnd"></param>
        /// <param name="htTable"></param>
        /// <returns></returns>
        public static object UpdateFieldName(string sourceStr, string matchStr, System.Collections.Hashtable htTable)
        {
            if (string.IsNullOrEmpty(sourceStr))
                return sourceStr;

            string s = sourceStr;
            foreach (string exp in Matches(sourceStr, matchStr))
            {
                string f = exp;
                foreach (string s1 in matchStr.Split('*'))
                {
                    f = f.Replace(s1, "");
                }
                string[] ff = (exp + ",,,,,").Split(',');
                if (htTable.ContainsKey(ff[0]))
                {
                    if (exp == sourceStr)
                    {
                        return FieldValueObj(htTable[ff[0]], ff[2]);
                    }
                    else
                    {
                        s = s.Replace(exp, FieldValue(htTable[ff[0]]));
                    }
                }
            }
            return s;
        }

    }
}
